#ifndef _WINDOW_H_
#define _WIDNOW_H_

#include "input.h"
#include "gui/gui.h"
#include "log/log.h"



/**
 * 引擎创建窗口使用此文件
 *@author cytus
 *@date 2022-09-04
 *
 */

/**
 * EWindowMode描述了窗口类的渲染模式
 * 可选的模式有;
 * 窗口模式
 * 无边框窗口模式
 * 全屏模式
 * 全屏窗口模式
 *
 */
enum class EWindowMode
{
    DESKTOP = SDL_WINDOW_SHOWN,
    BORDERLESS = SDL_WINDOW_BORDERLESS,
    FULLSCREEN = SDL_WINDOW_FULLSCREEN,
    FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN_DESKTOP,
};

/**
 * 窗口基类描述了一个引擎运行的窗口
 * 窗口基类不能直接创建窗口，创建什么样的窗口类是由引擎来决定的
 * 通常窗口类会创建一下两种窗口
 * 游戏运行窗口：
 * 游戏运行窗口没有编辑器界面，他单纯是一个游戏运行时看到的窗口
 * 游戏运行窗口仅在工程发布以后会被创建
 * 编辑器窗口：
 * 编辑器窗口是引擎在创建工程时启用的窗口，包含复杂的功能实现
 * 通常编辑器窗口会有多个子窗口，用于不同的编辑器功能实现
 *
 */
class UWindowBase
{
public:
    using Super = UWindowBase;
    UWindowBase();
    UWindowBase(const uString &caption, int32 width, int32 height, EWindowMode mode = EWindowMode::DESKTOP);
    UWindowBase(const UWindowBase &) = delete;
    virtual ~UWindowBase();

    void SetWindowVisible(uBoolean new_visible);
    void SetWindowFullscreen(uBoolean new_fullscreen);
    void SetWindowMaximize(uBoolean new_max);
    void SetWindowMinimize(uBoolean new_min);

    void SetWindowSize(int32 width, int32 height);
    void SetWindowPosition(int32 x, int32 y);
    void SetWindowCaption(const uString &caption);

    uBoolean IsWindowVisible() const;
    uBoolean IsWindowFullscreen() const;

    int32 GetWidth() const;
    int32 GetHeight() const;
    int32 GetPositionX() const;
    int32 GetPositionY() const;
    uString GetCaption() const;
    EWindowMode GetCurrentDisplayMode() const;

    uBoolean IsWindowActive() const;

    UInput* GetInputer();

    virtual void __test_draw() = 0;

    //========================================================================
    //下列函数由子类继承实现

    virtual void ClearBuffer() = 0;
    virtual void SwapBuffer() = 0;
    virtual void ProcEvent() = 0;

    //真正创建窗口的函数，无需用户调用
    virtual uBoolean __create() = 0;
    //窗口重绘以后会调用此函数，无需用户调用
    virtual void __resize_callback() = 0;

protected:
    SDL_Window *m_window;
    SDL_GLContext m_opengl_context;
    UInput* m_input;
    uBoolean m_active;
    EWindowMode m_mode;
    int32 m_width;
    int32 m_height;
    int32 m_position_x;
    int32 m_position_y;
    uString m_caption;
};

/**
 * 编辑器窗口包含一整套ImGUI的编辑器框架实现
 *
 */
class UEditorWindow : public UWindowBase
{
public:
    UEditorWindow();
    UEditorWindow(const uString &caption, int32 width, int32 height, EWindowMode mode = EWindowMode::DESKTOP);
    UEditorWindow(const UWindowBase &) = delete;
    virtual ~UEditorWindow();

    //

    virtual void ClearBuffer();
    virtual void SwapBuffer();
    virtual void ProcEvent();

    virtual void __test_draw();

    //真正创建窗口的函数，无需用户调用
    virtual uBoolean __create();
    //窗口重绘以后会调用此函数，无需用户调用
    virtual void __resize_callback();
};

/**
 * 游戏窗口不包含ImGUI的环境
 * 游戏内的UI创建是由引擎的Runtime下面的HUD实现的
 *
 */
class UGameWindow : public UWindowBase
{
public:
    UGameWindow();
    UGameWindow(const uString &caption, int32 width, int32 height, EWindowMode mode = EWindowMode::DESKTOP);
    UGameWindow(const UWindowBase &) = delete;
    virtual ~UGameWindow();

    //

    virtual void ClearBuffer();
    virtual void SwapBuffer();
    virtual void ProcEvent();

    //真正创建窗口的函数，无需用户调用
    virtual uBoolean __create();
    //窗口重绘以后会调用此函数，无需用户调用
    virtual void __resize_callback();

    virtual void __test_draw();
};

#endif